package com.learn.datatype.learndate;

import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;

/**
 * 功能：日期时间工具（线程安全）
 *
 * @author wsh
 * @date 2020/9/15
 */
public class LocalDateTimeUtil {
    public static final String PATTERN_YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";

    /**
     * 功能：格式化为"yyyy-MM-dd HH:mm:ss"
     *
     * @param localDateTime
     * @return
     * @author wsh
     * @date 2020/9/15
     */
    public static String format(LocalDateTime localDateTime) {
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(PATTERN_YYYY_MM_DD_HH_MM_SS);
        return localDateTime.format(dateTimeFormatter);
    }

    /**
     * 功能：解析为"yyyy-MM-dd HH:mm:ss"
     *
     * @param str
     * @return
     * @author wsh
     * @date 2020/9/15
     */
    public static LocalDateTime parse(String str) {
        LocalDateTime localDateTime = null;

        try {
            localDateTime = LocalDateTime.parse(str, DateTimeFormatter.ofPattern(PATTERN_YYYY_MM_DD_HH_MM_SS));
        } catch (Exception e) {
            // nothing
        }

        return localDateTime;
    }

    /**
     * 功能：本月第一天
     *
     * @return
     * @author wsh
     * @date 2020/9/15
     */
    public static LocalDateTime getFirstDayOfMonth(LocalDateTime localDateTime) {
        if (localDateTime == null) {
            localDateTime = LocalDateTime.now();
        }

        // 本月第一天
        localDateTime = localDateTime.with(TemporalAdjusters.firstDayOfMonth());
        // 带上时分秒
        return LocalDateTime.of(localDateTime.toLocalDate(), LocalTime.MIN);
    }

    /**
     * 功能：本月最后一天
     *
     * @return
     * @author wsh
     * @date 2020/9/15
     */
    public static LocalDateTime getLastDayOfMonth(LocalDateTime localDateTime) {
        if (localDateTime == null) {
            localDateTime = LocalDateTime.now();
        }

        // 本月最后一天
        localDateTime = localDateTime.with(TemporalAdjusters.lastDayOfMonth());
        // 带上时分秒
        return LocalDateTime.of(localDateTime.toLocalDate(), LocalTime.MAX);
    }

    /**
     * 功能：本年第一天
     *
     * @return
     * @author wsh
     * @date 2020/9/15
     */
    public static LocalDateTime getFirstDayOfYear(LocalDateTime localDateTime) {
        if (localDateTime == null) {
            localDateTime = LocalDateTime.now();
        }

        // 本月第一天
        localDateTime = localDateTime.with(TemporalAdjusters.firstDayOfYear());
        // 带上时分秒
        return LocalDateTime.of(localDateTime.toLocalDate(), LocalTime.MIN);
    }

    /**
     * 功能：本年最后一天
     *
     * @return
     * @author wsh
     * @date 2020/9/15
     */
    public static LocalDateTime getLastDayOfYear(LocalDateTime localDateTime) {
        if (localDateTime == null) {
            localDateTime = LocalDateTime.now();
        }

        // 本月最后一天
        localDateTime = localDateTime.with(TemporalAdjusters.lastDayOfYear());
        // 带上时分秒
        return LocalDateTime.of(localDateTime.toLocalDate(), LocalTime.MAX);
    }

    /**
     * 功能：时间计算，对指定单位做加/减运算
     *
     * @param localDateTime 开始时间，Null 则返回当前时间
     * @param unit          时间单位，支持年y、月M、日d、周w、时H、分m、秒s
     * @param value         时间值
     * @return
     * @author wsh
     * @date 2020/9/14
     */
    public static LocalDateTime dateTimeCalculate(LocalDateTime localDateTime, char unit, int value) {
        if (localDateTime == null) {
            localDateTime = LocalDateTime.now();
        }

        switch (unit) {
            case 'y':
                /**
                 * 以下方式都可以
                 * - 方式一：localDateTime.plusYears(value);
                 * - 方式二：localDateTime.plus(value, ChronoUnit.YEARS);
                 * - 方式三：通过 with 修改某些值，localDateTime.withYear(localDateTime.getYear() + value);
                 * - 方式四：通过 with 修改某些值，localDateTime.with(ChronoField.YEAR, localDateTime.getYear() + value);
                 */
                localDateTime = localDateTime.plusYears(value);
                // localDateTime = localDateTime.plus(value, ChronoUnit.YEARS);
                // localDateTime = localDateTime.withYear(localDateTime.getYear() + value);
                // localDateTime = localDateTime.with(ChronoField.YEAR, localDateTime.getYear() + value);
                break;
            case 'M':
                localDateTime = localDateTime.plusMonths(value);
                break;
            case 'd':
                localDateTime = localDateTime.plusDays(value);
                break;
            case 'w':
                localDateTime = localDateTime.plusWeeks(value);
                break;
            case 'H':
                localDateTime = localDateTime.plusHours(value);
                break;
            case 'm':
                localDateTime = localDateTime.plusMinutes(value);
                break;
            case 's':
                localDateTime = localDateTime.plusSeconds(value);
                break;
            default:
                break;
        }

        return localDateTime;
    }
}
